1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import time
17
18 from zope.interface import implements
19 from twisted.python import log
20 from twisted.internet import defer
21 from twisted.application import service
22
23 from buildbot import interfaces, util
24
26
27 """This is the master-side service which receives file change
28 notifications from a VCS. It keeps a log of these changes, enough to
29 provide for the HTML waterfall display, and to tell
30 temporarily-disconnected bots what they missed while they were
31 offline.
32
33 Change notifications come from two different kinds of sources. The first
34 is a PB service (servicename='changemaster', perspectivename='change'),
35 which provides a remote method called 'addChange', which should be
36 called with a dict that has keys 'filename' and 'comments'.
37
38 The second is a list of objects derived from the
39 L{buildbot.changes.base.ChangeSource} class. These are added with
40 .addSource(), which also sets the .changemaster attribute in the source
41 to point at the ChangeMaster. When the application begins, these will
42 be started with .start() . At shutdown time, they will be terminated
43 with .stop() . They must be persistable. They are expected to call
44 self.changemaster.addChange() with Change objects.
45
46 There are several different variants of the second type of source:
47
48 - L{buildbot.changes.mail.MaildirSource} watches a maildir for CVS
49 commit mail. It uses DNotify if available, or polls every 10
50 seconds if not. It parses incoming mail to determine what files
51 were changed.
52
53 """
54
55 implements(interfaces.IEventSource)
56
57 changeHorizon = None
58 lastPruneChanges = None
59 name = "changemanager"
60
66
71
75
77 """Deliver a file change event. The event should be a Change object.
78 This method will timestamp the object as it is received."""
79 msg = ("adding change, who %s, %d files, rev=%s, branch=%s, repository=%s, "
80 "comments %s, category %s, project %s" % (change.who, len(change.files),
81 change.revision, change.branch, change.repository,
82 change.comments, change.category, change.project))
83 log.msg(msg.encode('utf-8', 'replace'))
84
85
86
87
88 self.parent.addChange(change)
89
90 self.pruneChanges(change.number)
91
103
104
105
106 - def eventGenerator(self, branches=[], categories=[], committers=[], minTime=0):
109
120