Add persitent data store from trunk, sync the fetcher changes to use the persistent...
[bitbake.git] / lib / bb / event.py
1 # ex:ts=4:sw=4:sts=4:et
2 # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3 """
4 BitBake 'Event' implementation
5
6 Classes and functions for manipulating 'events' in the
7 BitBake build tools.
8 """
9
10 # Copyright (C) 2003, 2004  Chris Larson
11 #
12 # This program is free software; you can redistribute it and/or modify
13 # it under the terms of the GNU General Public License version 2 as
14 # published by the Free Software Foundation.
15 #
16 # This program is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 # GNU General Public License for more details.
20 #
21 # You should have received a copy of the GNU General Public License along
22 # with this program; if not, write to the Free Software Foundation, Inc.,
23 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
25 import os, re
26 import bb.utils
27
28 class Event:
29     """Base class for events"""
30     type = "Event"
31
32     def __init__(self, d):
33         self._data = d
34
35     def getData(self):
36         return self._data
37
38     def setData(self, data):
39         self._data = data
40
41     data = property(getData, setData, None, "data property")
42
43 NotHandled = 0
44 Handled = 1
45
46 Registered        = 10
47 AlreadyRegistered = 14
48
49 # Internal
50 _handlers = []
51 _handlers_dict = {}
52
53 def tmpHandler(event):
54     """Default handler for code events"""
55     return NotHandled
56
57 def defaultTmpHandler():
58     tmp = "def tmpHandler(e):\n\t\"\"\"heh\"\"\"\n\treturn NotHandled"
59     comp = bb.utils.better_compile(tmp, "tmpHandler(e)", "bb.event.defaultTmpHandler")
60     return comp
61
62 def fire(event):
63     """Fire off an Event"""
64     for h in _handlers:
65         if type(h).__name__ == "code":
66             exec(h)
67             if tmpHandler(event) == Handled:
68                 return Handled
69         else:
70             if h(event) == Handled:
71                 return Handled
72     return NotHandled
73
74 def register(name, handler):
75     """Register an Event handler"""
76
77     # already registered
78     if name in _handlers_dict:
79         return AlreadyRegistered
80
81     if handler is not None:
82 #       handle string containing python code
83         if type(handler).__name__ == "str":
84             _registerCode(handler)
85         else:
86             _handlers.append(handler)
87
88         _handlers_dict[name] = 1
89         return Registered
90
91 def _registerCode(handlerStr):
92     """Register a 'code' Event.
93        Deprecated interface; call register instead.
94
95        Expects to be passed python code as a string, which will
96        be passed in turn to compile() and then exec().  Note that
97        the code will be within a function, so should have had
98        appropriate tabbing put in place."""
99     tmp = "def tmpHandler(e):\n%s" % handlerStr
100     comp = bb.utils.better_compile(tmp, "tmpHandler(e)", "bb.event._registerCode")
101 #   prevent duplicate registration
102     _handlers.append(comp)
103
104 def remove(name, handler):
105     """Remove an Event handler"""
106
107     _handlers_dict.pop(name)
108     if type(handler).__name__ == "str":
109         return _removeCode(handler)
110     else:
111         _handlers.remove(handler)
112
113 def _removeCode(handlerStr):
114     """Remove a 'code' Event handler
115        Deprecated interface; call remove instead."""
116     tmp = "def tmpHandler(e):\n%s" % handlerStr
117     comp = bb.utils.better_compile(tmp, "tmpHandler(e)", "bb.event._removeCode")
118     _handlers.remove(comp)
119
120 def getName(e):
121     """Returns the name of a class or class instance"""
122     if getattr(e, "__name__", None) == None:
123         return e.__class__.__name__
124     else:
125         return e.__name__
126
127
128 class PkgBase(Event):
129     """Base class for package events"""
130
131     def __init__(self, t, d):
132         self._pkg = t
133         Event.__init__(self, d)
134
135     def getPkg(self):
136         return self._pkg
137
138     def setPkg(self, pkg):
139         self._pkg = pkg
140
141     pkg = property(getPkg, setPkg, None, "pkg property")
142
143
144 class BuildBase(Event):
145     """Base class for bbmake run events"""
146
147     def __init__(self, n, p, c, failures = 0):
148         self._name = n
149         self._pkgs = p
150         Event.__init__(self, c)
151         self._failures = failures
152
153     def getPkgs(self):
154         return self._pkgs
155
156     def setPkgs(self, pkgs):
157         self._pkgs = pkgs
158
159     def getName(self):
160         return self._name
161
162     def setName(self, name):
163         self._name = name
164
165     def getCfg(self):
166         return self.data
167
168     def setCfg(self, cfg):
169         self.data = cfg
170
171     def getFailures(self):
172         """
173         Return the number of failed packages
174         """
175         return self._failures
176
177     pkgs = property(getPkgs, setPkgs, None, "pkgs property")
178     name = property(getName, setName, None, "name property")
179     cfg = property(getCfg, setCfg, None, "cfg property")
180
181
182 class DepBase(PkgBase):
183     """Base class for dependency events"""
184
185     def __init__(self, t, data, d):
186         self._dep = d
187         PkgBase.__init__(self, t, data)
188
189     def getDep(self):
190         return self._dep
191
192     def setDep(self, dep):
193         self._dep = dep
194
195     dep = property(getDep, setDep, None, "dep property")
196
197
198 class PkgStarted(PkgBase):
199     """Package build started"""
200
201
202 class PkgFailed(PkgBase):
203     """Package build failed"""
204
205
206 class PkgSucceeded(PkgBase):
207     """Package build completed"""
208
209
210 class BuildStarted(BuildBase):
211     """bbmake build run started"""
212
213
214 class BuildCompleted(BuildBase):
215     """bbmake build run completed"""
216
217
218 class UnsatisfiedDep(DepBase):
219     """Unsatisfied Dependency"""
220
221
222 class RecursiveDep(DepBase):
223     """Recursive Dependency"""
224
225 class NoProvider(Event):
226     """No Provider for an Event"""
227
228     def __init__(self, item, data,runtime=False):
229         Event.__init__(self, data)
230         self._item = item
231         self._runtime = runtime
232
233     def getItem(self):
234         return self._item
235
236     def isRuntime(self):
237         return self._runtime
238
239 class MultipleProviders(Event):
240     """Multiple Providers"""
241
242     def  __init__(self, item, candidates, data, runtime = False):
243         Event.__init__(self, data)
244         self._item = item
245         self._candidates = candidates
246         self._is_runtime = runtime
247
248     def isRuntime(self):
249         """
250         Is this a runtime issue?
251         """
252         return self._is_runtime
253
254     def getItem(self):
255         """
256         The name for the to be build item
257         """
258         return self._item
259
260     def getCandidates(self):
261         """
262         Get the possible Candidates for a PROVIDER.
263         """
264         return self._candidates