36 |
36 |
_RESET_SEQ = None
|
37 |
37 |
|
38 |
38 |
|
|
39 |
# List of all hooks
|
|
40 |
_hooks = []
|
|
41 |
|
|
42 |
|
39 |
43 |
def _SetupColours():
|
40 |
44 |
"""Initializes the colour constants.
|
41 |
45 |
|
... | ... | |
214 |
218 |
FormatWarning = lambda text: _FormatWithColor(text, _WARNING_SEQ)
|
215 |
219 |
FormatError = lambda text: _FormatWithColor(text, _ERROR_SEQ)
|
216 |
220 |
FormatInfo = lambda text: _FormatWithColor(text, _INFO_SEQ)
|
|
221 |
|
|
222 |
|
|
223 |
def LoadHooks():
|
|
224 |
"""Load all QA hooks.
|
|
225 |
|
|
226 |
"""
|
|
227 |
hooks_dir = qa_config.get('options', {}).get('hooks-dir', None)
|
|
228 |
if not hooks_dir:
|
|
229 |
return
|
|
230 |
if hooks_dir not in sys.path:
|
|
231 |
sys.path.insert(0, hooks_dir)
|
|
232 |
for name in utils.ListVisibleFiles(hooks_dir):
|
|
233 |
if name.endswith('.py'):
|
|
234 |
# Load and instanciate hook
|
|
235 |
_hooks.append(__import__(name[:-3], None, None, ['']).hook())
|
|
236 |
|
|
237 |
|
|
238 |
class QaHookContext:
|
|
239 |
name = None
|
|
240 |
phase = None
|
|
241 |
success = None
|
|
242 |
args = None
|
|
243 |
kwargs = None
|
|
244 |
|
|
245 |
|
|
246 |
def _CallHooks(ctx):
|
|
247 |
"""Calls all hooks with the given context.
|
|
248 |
|
|
249 |
"""
|
|
250 |
if not _hooks:
|
|
251 |
return
|
|
252 |
|
|
253 |
name = "%s-%s" % (ctx.phase, ctx.name)
|
|
254 |
if ctx.success is not None:
|
|
255 |
msg = "%s (success=%s)" % (name, ctx.success)
|
|
256 |
else:
|
|
257 |
msg = name
|
|
258 |
print FormatInfo("Begin %s" % msg)
|
|
259 |
for hook in _hooks:
|
|
260 |
hook.run(ctx)
|
|
261 |
print FormatInfo("End %s" % name)
|
|
262 |
|
|
263 |
|
|
264 |
def DefineHook(name):
|
|
265 |
"""Wraps a function with calls to hooks.
|
|
266 |
|
|
267 |
Usage: prefix function with @qa_utils.DefineHook(...)
|
|
268 |
|
|
269 |
"""
|
|
270 |
def wrapper(fn):
|
|
271 |
def new_f(*args, **kwargs):
|
|
272 |
# Create context
|
|
273 |
ctx = QaHookContext()
|
|
274 |
ctx.name = name
|
|
275 |
ctx.phase = 'pre'
|
|
276 |
ctx.args = args
|
|
277 |
ctx.kwargs = kwargs
|
|
278 |
|
|
279 |
_CallHooks(ctx)
|
|
280 |
try:
|
|
281 |
ctx.phase = 'post'
|
|
282 |
ctx.success = True
|
|
283 |
try:
|
|
284 |
# Call real function
|
|
285 |
return fn(*args, **kwargs)
|
|
286 |
except:
|
|
287 |
ctx.success = False
|
|
288 |
raise
|
|
289 |
finally:
|
|
290 |
_CallHooks(ctx)
|
|
291 |
|
|
292 |
# Override function metadata
|
|
293 |
new_f.func_name = fn.func_name
|
|
294 |
new_f.func_doc = fn.func_doc
|
|
295 |
|
|
296 |
return new_f
|
|
297 |
|
|
298 |
return wrapper
|