event.py 6.8 KB

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