event.py: Add ConfigParsed Event after configuration parsing is complete
[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 class ConfigParsed(Event):
128     """Configuration Parsing Complete"""
129
130 class PkgBase(Event):
131     """Base class for package events"""
132
133     def __init__(self, t, d):
134         self._pkg = t
135         Event.__init__(self, d)
136
137     def getPkg(self):
138         return self._pkg
139
140     def setPkg(self, pkg):
141         self._pkg = pkg
142
143     pkg = property(getPkg, setPkg, None, "pkg property")
144
145
146 class BuildBase(Event):
147     """Base class for bbmake run events"""
148
149     def __init__(self, n, p, c, failures = 0):
150         self._name = n
151         self._pkgs = p
152         Event.__init__(self, c)
153         self._failures = failures
154
155     def getPkgs(self):
156         return self._pkgs
157
158     def setPkgs(self, pkgs):
159         self._pkgs = pkgs
160
161     def getName(self):
162         return self._name
163
164     def setName(self, name):
165         self._name = name
166
167     def getCfg(self):
168         return self.data
169
170     def setCfg(self, cfg):
171         self.data = cfg
172
173     def getFailures(self):
174         """
175         Return the number of failed packages
176         """
177         return self._failures
178
179     pkgs = property(getPkgs, setPkgs, None, "pkgs property")
180     name = property(getName, setName, None, "name property")
181     cfg = property(getCfg, setCfg, None, "cfg property")
182
183
184 class DepBase(PkgBase):
185     """Base class for dependency events"""
186
187     def __init__(self, t, data, d):
188         self._dep = d
189         PkgBase.__init__(self, t, data)
190
191     def getDep(self):
192         return self._dep
193
194     def setDep(self, dep):
195         self._dep = dep
196
197     dep = property(getDep, setDep, None, "dep property")
198
199
200 class PkgStarted(PkgBase):
201     """Package build started"""
202
203
204 class PkgFailed(PkgBase):
205     """Package build failed"""
206
207
208 class PkgSucceeded(PkgBase):
209     """Package build completed"""
210
211
212 class BuildStarted(BuildBase):
213     """bbmake build run started"""
214
215
216 class BuildCompleted(BuildBase):
217     """bbmake build run completed"""
218
219
220 class UnsatisfiedDep(DepBase):
221     """Unsatisfied Dependency"""
222
223
224 class RecursiveDep(DepBase):
225     """Recursive Dependency"""
226
227 class NoProvider(Event):
228     """No Provider for an Event"""
229
230     def __init__(self, item, data,runtime=False):
231         Event.__init__(self, data)
232         self._item = item
233         self._runtime = runtime
234
235     def getItem(self):
236         return self._item
237
238     def isRuntime(self):
239         return self._runtime
240
241 class MultipleProviders(Event):
242     """Multiple Providers"""
243
244     def  __init__(self, item, candidates, data, runtime = False):
245         Event.__init__(self, data)
246         self._item = item
247         self._candidates = candidates
248         self._is_runtime = runtime
249
250     def isRuntime(self):
251         """
252         Is this a runtime issue?
253         """
254         return self._is_runtime
255
256     def getItem(self):
257         """
258         The name for the to be build item
259         """
260         return self._item
261
262     def getCandidates(self):
263         """
264         Get the possible Candidates for a PROVIDER.
265         """
266         return self._candidates