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 16from twisted.internet import defer 17from zope.interface import implementer 18 19from buildbot import interfaces 20from buildbot.reporters import utils 21from buildbot.reporters.message import MessageFormatter 22from buildbot.reporters.message import MessageFormatterRenderable 23 24from .utils import BuildStatusGeneratorMixin 25 26 27@implementer(interfaces.IReportGenerator) 28class BuildStatusGenerator(BuildStatusGeneratorMixin): 29 30 wanted_event_keys = [ 31 ('builds', None, 'finished'), 32 ] 33 34 compare_attrs = ['formatter'] 35 36 def __init__(self, mode=("failing", "passing", "warnings"), 37 tags=None, builders=None, schedulers=None, branches=None, 38 subject="Buildbot %(result)s in %(title)s on %(builder)s", 39 add_logs=False, add_patch=False, report_new=False, message_formatter=None): 40 super().__init__(mode, tags, builders, schedulers, branches, subject, add_logs, add_patch) 41 self.formatter = message_formatter 42 if self.formatter is None: 43 self.formatter = MessageFormatter() 44 45 if report_new: 46 self.wanted_event_keys = [ 47 ('builds', None, 'finished'), 48 ('builds', None, 'new'), 49 ] 50 51 @defer.inlineCallbacks 52 def generate(self, master, reporter, key, build): 53 _, _, event = key 54 is_new = event == 'new' 55 want_previous_build = False if is_new else self._want_previous_build() 56 57 yield utils.getDetailsForBuild(master, build, 58 want_properties=self.formatter.want_properties, 59 want_steps=self.formatter.want_steps, 60 want_previous_build=want_previous_build, 61 want_logs=self.formatter.want_logs, 62 want_logs_content=self.formatter.want_logs_content) 63 64 if not self.is_message_needed_by_props(build): 65 return None 66 if not is_new and not self.is_message_needed_by_results(build): 67 return None 68 69 report = yield self.build_message(self.formatter, master, reporter, build) 70 return report 71 72 def _want_previous_build(self): 73 return "change" in self.mode or "problem" in self.mode 74 75 76@implementer(interfaces.IReportGenerator) 77class BuildStartEndStatusGenerator(BuildStatusGeneratorMixin): 78 79 wanted_event_keys = [ 80 ('builds', None, 'new'), 81 ('builds', None, 'finished'), 82 ] 83 84 compare_attrs = ['start_formatter', 'end_formatter'] 85 86 def __init__(self, tags=None, builders=None, schedulers=None, branches=None, add_logs=False, 87 add_patch=False, start_formatter=None, end_formatter=None): 88 89 super().__init__('all', tags, builders, schedulers, branches, None, add_logs, add_patch) 90 self.start_formatter = start_formatter 91 if self.start_formatter is None: 92 self.start_formatter = MessageFormatterRenderable('Build started.') 93 self.end_formatter = end_formatter 94 if self.end_formatter is None: 95 self.end_formatter = MessageFormatterRenderable('Build done.') 96 97 @defer.inlineCallbacks 98 def generate(self, master, reporter, key, build): 99 _, _, event = key 100 is_new = event == 'new' 101 102 formatter = self.start_formatter if is_new else self.end_formatter 103 104 yield utils.getDetailsForBuild(master, build, 105 want_properties=formatter.want_properties, 106 want_steps=formatter.want_steps, 107 want_logs=formatter.want_logs, 108 want_logs_content=formatter.want_logs_content) 109 110 if not self.is_message_needed_by_props(build): 111 return None 112 113 report = yield self.build_message(formatter, master, reporter, build) 114 return report 115