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